﻿using XinLife.Application.Interface;
using XinLife.Common;
using XinLife.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using XinLife.Core.Model;
using Microsoft.AspNetCore.Authorization;
using XinLife.Model.Dto;
using XinLife.Common.Filters;
using static XinLife.Common.StartupUtil;
using XinLife.Core.Helper;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using XinLife.Application;
using System.Runtime.CompilerServices;
using System.Net.Sockets;
using System.ComponentModel.DataAnnotations;
using StackExchange.Profiling.Internal;

namespace XinLife.Controllers.Admin
{
    /// <summary>
    /// 登陆控制器
    /// </summary>
    public class LoginController : BaseController
    {
        private IUserMsgService _userMsgService;
        private IUserService _userService;
        private IModuleService _moduleService;
        private readonly JwtOption _jwtOption;

        public LoginController(IUserService userService, IModuleService moduleService, IUserMsgService userMsgService, JwtOption jwtOption)
        {
            _userService = userService;
            _moduleService = moduleService;
            _userMsgService = userMsgService;
            _jwtOption = jwtOption;
        }
        /// <summary>
        /// 首页判断是否登录
        /// </summary>
        /// <remarks>
        /// 1.
        /// 2.
        /// </remarks>
        /// <returns></returns>
        [HttpPost]
        public AjaxResult IsLogin()
        {
            return Success("ok");
        }
        /// <summary>
        /// 注销
        /// </summary>
        [HttpPost, HttpGet]
        public async Task<object> Logout()
        {
            await HttpContext.SignOutAsync();
            return Success("注销成功");
        }
        /// <summary>
        /// 用户登录
        /// </summary>
        [AllowAnonymous, HttpPost]
        [WriteLog(false)]
        public async Task<AjaxResult> Login([FromForm] LoginModel login)
        {
            if (!ModelState.IsValid)
            {
                return Error(ModelState);
            }
            var user = await _userService.GetUserRoleNameStr(login.UserName, login.PassWord);
            if (user != null && !user.cEnabled)
            {
                return Error("账号已停用!");
            }
            if (user != null)
            {
                var claims = new List<Claim> {
                    new Claim(ClaimTypes.NameIdentifier,user.cId),
                    new Claim(ClaimTypes.Name, login.UserName),
                    new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_jwtOption.Expiration).ToString()) };
                //cookie认证
                var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                var principal = new ClaimsPrincipal(identity);
                await HttpContext.SignInAsync(principal);

                //2. 进行JWT签名
                var token = JwtToken.BuildJwtToken(claims.ToArray(), _jwtOption);

                //用户菜单查询
                var data = await _moduleService.GetUserModule(user.cId, user.Roles.Any(t => t.cName.Contains("超级管理员")));
                Func<List<Module>, string, List<ModuleOutputDto>> res = null;
                //递归0.0
                res = (List<Module> list, string parentid) =>
                {
                    var items = list.FindAll(t => t.cParentId == parentid).OrderBy(t => t.cSortCode).ToList();

                    var b = new List<ModuleOutputDto>();

                    items.ForEach(t =>
                    {
                        b.Add(new ModuleOutputDto()
                        {
                            Id = t.cId,
                            Title = t.cTitle,
                            Icon = t.cIcon,
                            Name = t.cTitle,
                            CompName = t.cName,
                            CompPath = t.cPath,
                            Path = t.cPath,
                            Children = res(list, t.cId)
                        });
                    });
                    return b;
                };

                //用户页面功能权限查询 
                var buttons = new Dictionary<string, List<object>>();
                var buttonList = await _moduleService.GetUserModuleButtons(user.cId, user.Roles.Any(t => t.cName.Contains("超级管理员")));
                foreach (var item in buttonList)
                {
                    if (item.cModuleName == null) continue;

                    if (!buttons.Keys.Contains(item.cModuleId))
                    {
                        buttons[item.cModuleId] = new List<object>();
                    }

                    buttons[item.cModuleId].Add(new { item.cIcon, item.cTitle, item.cEnCode, item.cPosition });
                }
                //                                                                                                                                                                                             ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้";
                await _userService.UpdateLoginTime(user.cId);
                await _userMsgService.EditUserMsg(new UserMsg()
                {
                    cSenderName = "系统消息",
                    cTitle = "欢迎登陆",
                    cContent = $"尊敬的用户您好,欢迎您的到来！",
                    cReceiverId = user.cId,
                    cReceiverName = user.cName
                });
                Request.HttpContext.Items["user"] = user;
                await _userService.LoginInfo();
                return Success("登陆成功",
                    new
                    {
                        user = new { cName = user.cName, cUserName = user.cUserName, cId = user.cId, roles = user.Roles.Select(t => t.cName) },
                        auth_token = token,
                        modules = res(data, "0"),
                        buttons
                    });
            }
            else
            {
                return Error("登陆失败");
            }
        }


        /// <summary>
        /// swagger登录
        /// </summary>
        [AllowAnonymous, HttpPost]
        public async Task<AjaxResult> SwaggerLogin([FromBody, Required] LoginModel login)
        {
            string key = Appsettings.app("AppSetting", "SwaggerKey");
            if (login.UserName == "xin" && login.PassWord == "123@@Xin")
            {
                string ticket = SecurityUtils.AesEncrypt(new { Expiration = DateTimeOffset.Now.AddMinutes(120).ToFileTime() }.ToJson(), key);
                return Success(new { ticket = Uri.EscapeDataString(ticket) });
            }
            else
            {
                return Error("登陆失败");
            }
        }
        /// <summary>
        /// QQ登录
        /// </summary>
        [AllowAnonymous, HttpPost]
        public async Task<AjaxResult> QQLogin(string code)
        {
            return await _userService.QQLogin(code);
        }
        /// <summary>
        /// 解锁
        /// </summary>
        [HttpPost]
        public async Task<AjaxResult> UnLock([FromForm] LoginModel login)
        {
            if (string.IsNullOrEmpty(login.UserName) || string.IsNullOrEmpty(login.PassWord))
            {
                return Error("用户名或密码不能为空");
            }
            var user = await _userService.GetUserRoleNameStr(login.UserName, login.PassWord);
            if (user == null)
            {
                return Error("密码错误");
            }
            return Success("ok");
        }

        /// <summary>
        /// 获取滑动图片
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous, HttpGet]
        public async Task<AjaxResult> VerifyImg()
        {
            var baseDirec = Directory.GetCurrentDirectory();  // 根目录
            var imgPath = $"webfile/img/verify_img";  // 文件上传目录
            string[] imageFiles = Directory.GetFiles(Path.Combine(baseDirec, imgPath));

            Random random = new Random();
            int randomIndex = random.Next(0, imageFiles.Length);
            string imagePath = imageFiles[randomIndex];

            var data = ImageCropper.CropImage(imagePath, 50, 50);
            return Success(new { id = Guid.NewGuid().ToString("N"), data.Item1, data.Item2, left = data.Item3 });
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<AjaxResult> SetPwd([FromForm] string oldPassword, [FromForm] string password)
        {
            return await _userService.SetPwd(oldPassword, password);
        }
    }
}
